diff options
Diffstat (limited to 'src/pages/shop/product/[slug].js')
| -rw-r--r-- | src/pages/shop/product/[slug].js | 305 |
1 files changed, 0 insertions, 305 deletions
diff --git a/src/pages/shop/product/[slug].js b/src/pages/shop/product/[slug].js deleted file mode 100644 index 61692c1c..00000000 --- a/src/pages/shop/product/[slug].js +++ /dev/null @@ -1,305 +0,0 @@ -import Link from "@/components/elements/Link" -import { useRouter } from "next/router" -import { useEffect, useState } from "react" -import Header from "@/components/layouts/Header" -import apiOdoo from "@/core/utils/apiOdoo" -import { createSlug, getIdFromSlug } from "@/core/utils/slug" -import currencyFormat from "@/core/utils/currencyFormat" -import Layout from "@/components/layouts/Layout" -import { createOrUpdateItemCart } from "@/core/utils/cart" -import toast from "react-hot-toast" -import Footer from "@/components/layouts/Footer" -import Image from "@/components/elements/Image" -import LineDivider from "@/components/elements/LineDivider" -import { HeartIcon as HeartIconSolid } from "@heroicons/react/24/solid" -import { useAuth } from "@/core/utils/auth" -import { HeartIcon } from "@heroicons/react/24/outline" -import LazyLoad from "react-lazy-load" -import ProductSimilar from "@/components/products/ProductSimilar" - -export async function getServerSideProps( context ) { - const { slug } = context.query - let product = await apiOdoo('GET', '/api/v1/product/' + getIdFromSlug(slug)) - if (product?.length == 1) { - product = product[0] - product.description = product.description.replaceAll('<p>', '||p||') - product.description = product.description.replaceAll('</p>', '||/p||') - product.description = product.description.replace(/(<([^>]+)>)/gi, ' ') - product.description = product.description.replaceAll('||p||', '<p>') - product.description = product.description.replaceAll('||/p||', '</p>') - product.description = product.description.trim() - } - return { props: { product } } -} - -export default function ProductDetail({ product }) { - const [ auth ] = useAuth() - const router = useRouter() - const { slug } = router.query - const [selectedVariant, setSelectedVariant] = useState("") - const [quantity, setQuantity] = useState("1") - const [activeVariant, setActiveVariant] = useState({ - id: product.id, - code: product.code, - price: product.lowest_price, - stock: product.stock_total, - weight: product.weight, - attributes: '', - }) - - const [ isAddedToWishlist, setAddedToWishlist ] = useState(false) - const [ activeTab, setActiveTab ] = useState('specification') - - const addOrDeleteWishlist = async () => { - if (auth) { - await apiOdoo('POST', `/api/v1/user/${auth.id}/wishlist/create-or-delete`, { - product_id: product.id - }) - if (isAddedToWishlist) { - toast.success('Berhasil menghapus dari wishlist') - } else { - toast.success('Berhasil menambahkan ke wishlist') - } - setAddedToWishlist(!isAddedToWishlist) - } else { - toast.error('Login terlebih dahulu untuk melanjutkan') - router.push('/login') - } - } - - useEffect(() => { - if (auth) { - const checkWishlist = async () => { - const wishlist = await apiOdoo('GET', `/api/v1/user/${auth.id}/wishlist?product_id=${product.id}`) - setAddedToWishlist(wishlist.product_total > 0 ? true : false) - } - checkWishlist() - } - }, [ auth, product ]) - - useEffect(() => { - if (product.variants.length == 1) { - setSelectedVariant(product.variants[0].id) - } - }, [ product ]) - - useEffect(() => { - if (selectedVariant != '') { - let newActiveVariant = product.variants.filter((variant) => { - return variant.id == selectedVariant - }) - - if (newActiveVariant.length == 1) { - newActiveVariant = newActiveVariant[0] - setActiveVariant({ - id: newActiveVariant.id, - code: newActiveVariant.code, - price: newActiveVariant.price, - stock: newActiveVariant.stock, - weight: newActiveVariant.weight, - attributes: newActiveVariant.attributes.join(', '), - }) - } - } - }, [selectedVariant, product]) - - const onchangeVariant = (e) => { - setSelectedVariant(e.target.value) - } - - const onChangeQuantity = (e) => { - let inputValue = e.target.value - inputValue = parseInt(inputValue) - inputValue = Math.floor(inputValue) - setQuantity(inputValue) - } - - const addItemToCart = () => { - if (product.variant_total > 1 && !selectedVariant) { - toast.error('Pilih varian terlebih dahulu untuk menambahkan ke keranjang', { duration: 2000 }) - return false - } - - if (quantity > 0) { - toast.success('Berhasil menambahkan ke keranjang', { duration: 1500 }) - createOrUpdateItemCart(activeVariant.id, parseInt(quantity)) - } else { - toast.error('Jumlah barang yang ditambahkan minimal 1 pcs', { duration: 2000 }) - } - - return true - } - - const checkoutProduct = () => { - if (!auth) { - toast.error('Login terlebih dahulu untuk melanjutkan', { duration: 2000 }) - router.push('/login') - return - } - if (product.variant_total > 1 && !selectedVariant) { - toast.error('Pilih varian terlebih dahulu untuk melanjutkan pembelian', { duration: 2000 }) - return - } - if (quantity < 0) { - toast.error('Jumlah barang yang ditambahkan minimal 1 pcs', { duration: 2000 }) - return - } - router.push(`/shop/checkout?product_id=${activeVariant.id}&qty=${quantity}`) - } - - const TabButton = ({ children, name }) => ( - <button - type="button" - className={`font-medium pb-1 ${activeTab == name ? 'text-red_r-11 border-b border-red_r-10' : 'text-gray_r-11'}`} - onClick={() => setActiveTab(name)} - > - { children } - </button> - ) - - return ( - <> - <Header title={`${product.name} - Indoteknik`}/> - <Layout> - <Image - src={product.image} - alt={product.name} - className="border-b border-gray_r-6 w-full h-[300px] object-contain object-center bg-white" - /> - - <div className="p-4"> - <div className="flex justify-between gap-x-3"> - <div> - <Link href={'/shop/brands/' + createSlug(product.manufacture.name, product.manufacture.id)}> - {product.manufacture.name ?? '-'} - </Link> - <h1 className="h2 mt-2 mb-3">{product.name}{activeVariant.attributes ? ' - ' + activeVariant.attributes : ''}</h1> - </div> - <button className="h-fit" onClick={addOrDeleteWishlist}> - { isAddedToWishlist && ( - <HeartIconSolid className="w-6 text-red_r-10" /> - ) } - { !isAddedToWishlist && ( - <HeartIcon className="w-6" /> - ) } - </button> - </div> - - {product.variant_total > 1 && !selectedVariant && product.lowest_price.price > 0 ? ( - <p className="text-caption-2 text-gray-800 mb-1">Harga mulai dari:</p> - ) : ''} - - {product.lowest_price.discount_percentage > 0 ? ( - <div className="flex gap-x-1 items-center mb-1"> - <p className="text-caption-2 text-gray_r-11 line-through">{currencyFormat(activeVariant.price.price)}</p> - <span className="badge-solid-red">{activeVariant.price.discount_percentage}%</span> - </div> - ) : ''} - - {product.lowest_price.price > 0 ? ( - <p className="text-body-lg font-semibold">{currencyFormat(activeVariant.price.price_discount)}</p> - ) : ( - <p className="text-gray_r-11">Dapatkan harga terbaik, <a href="">hubungi kami.</a></p> - )} - </div> - - <LineDivider /> - - <div className="p-4"> - <div className=""> - <label className="form-label mb-2">Pilih: <span className="text-gray_r-11 font-normal">{product.variant_total} Varian</span></label> - <select name="variant" className="form-input" value={selectedVariant} onChange={onchangeVariant} > - <option value="" disabled={selectedVariant != "" ? true : false}>Pilih Varian...</option> - {product.variants.length > 1 ? ( - product.variants.map((variant) => { - return ( - <option key={variant.id} value={variant.id}>{variant.attributes.join(', ')}</option> - ) - }) - ) : ( - <option key={product.variants[0].id} value={product.variants[0].id}>{product.variants[0].name}</option> - )} - </select> - </div> - - <label htmlFor="quantity" className="form-label mb-1 mt-3">Jumlah</label> - <div className="flex gap-x-2 mt-2"> - <input type="number" name="quantity" id="quantity" className="form-input h-full w-5/12 text-center" value={quantity} onChange={onChangeQuantity} /> - - <button - className="btn-yellow w-full" - onClick={addItemToCart} - disabled={(product.lowest_price.price == 0 ? true : false)} - > - Keranjang - </button> - <button - onClick={checkoutProduct} - className="btn-solid-red w-full" - > - Beli - </button> - </div> - </div> - - <LineDivider /> - - <div className="p-4"> - <h2 className="font-bold mb-4">Informasi Produk</h2> - <div className="flex gap-x-3 mb-4"> - <TabButton name="specification">Spesifikasi</TabButton> - <TabButton name="description">Deskripsi</TabButton> - <TabButton name="information">Info Penting</TabButton> - </div> - - <div className={`border border-gray_r-6 rounded divide-y ${activeTab == 'specification' ? 'block' : 'hidden'}`}> - <ProductSpecification label="Jumlah Varian"> - <p className="text-gray-800">{product.variant_total} Varian</p> - </ProductSpecification> - <ProductSpecification label="Nomor SKU"> - <p className="text-gray-800" id="sku_number">SKU-{activeVariant.id}</p> - </ProductSpecification> - <ProductSpecification label="Part Number"> - <p className="text-gray-800" id="part_number">{activeVariant.code}</p> - </ProductSpecification> - <ProductSpecification label="Stok"> - <div className="flex gap-x-2" id="stock"> - {activeVariant.stock > 0 ? (activeVariant.stock > 5 && ( - <> - <div className="badge-solid-red">Ready Stock</div> - <div className="badge-gray">{activeVariant.stock > 5 ? '> 5' : '< 5'}</div> - </> - )) : '0'} - </div> - </ProductSpecification> - <ProductSpecification label="Part Number"> - <p className="text-gray-800" id="weight">{activeVariant.weight > 0 ? activeVariant.weight : '1'} KG</p> - </ProductSpecification> - </div> - - <div - className={`text-gray-800 leading-7 ${activeTab == 'description' ? 'block' : 'hidden'}`} - dangerouslySetInnerHTML={{__html: (product.description != '' ? product.description : 'Belum ada deskripsi produk.')}} - ></div> - </div> - - <LineDivider /> - - <LazyLoad> - <ProductSimilar productId={getIdFromSlug(slug || '')} /> - </LazyLoad> - - <Footer /> - </Layout> - </> - ) -} - -const ProductSpecification = ({ children, ...props }) => { - return ( - <div className="flex p-3 justify-between items-center gap-x-1"> - <h3 className="text-gray-900">{ props.label }</h3> - { children } - </div> - ) -}
\ No newline at end of file |
